import Taro, { Component } from '@tarojs/taro'
import { View } from '@tarojs/components'
import { AtActivityIndicator } from 'taro-ui'
import styles from './index.module.less'

// import styles from './default.module.less'

export default class extends Component {

    constructor(props) {
        super(props)
        this.state = {
            playedWidthState: 0
        }
    }

    componentDidMount() {
        // setInterval(() => {
        //     this.setState((state, props) => ({
        //         progess: (state.progess + 1) % 100
        //       }));
        // }, 300);
    }

    // 点击进度条，回调change事件，或者 setstate playedWidthState
    onBarBodyClick(e) {
        e.stopPropagation();
        this.userOperation = true;
        console.log('onBarBodyClick');

        // clientWidth 为BarBody元素的宽度
        const { offsetX, currentTarget: { clientWidth } } = e
        const { onChange } = this.props
        const currentTime = this.props.totalTime * (offsetX / clientWidth);
        // console.log(e);
        onChange ? onChange(currentTime) : this.setState({ playedWidthState: offsetX })
    };

    onBallTouched(e) {
        console.log('onBallTouched');
        e.stopPropagation();
        console.log('onBallTouched:', this.played)
        // 记录小球的鼠标位置
        this.ballCurPageX = e.targetTouches[0].pageX;
        // 当点击小球的时候，想办法停止props.currentTime的更新，否则导致滑动失败。
    }

    onTouchMoved(e) {
        console.log('onTouchMoved');
        e.stopPropagation();
        // 如果null，则说明刚才没有BallTouched，则忽略本事件
        if (this.ballCurPageX === null) {
            return
        }
        // 标记用户手动触发为true；该标志用来在渲染的时候判断是否使用过渡动画。
        this.userOperation = true;
        // barBodyWidth为滑动容器最大宽度
        const barBodyWidth = this.barBody.vnode.dom.clientWidth;
        // 计算滑动离。注意：滑动距离并不等于played的宽度。
        const moveDistance = e.targetTouches[0].pageX - this.ballCurPageX;
        // 计算进度条最新的宽度; 2020年4月2日发现bug:this.state.playedWidthState初始值不一定正确
        // const playedWidth = this.state.playedWidthState + moveDistance
        // 计算进度条最新的宽度
        const playedWidth = this.played.vnode.dom.clientWidth + moveDistance
        // 处理边界问题, 确认最终的宽度
        const playedWidthState = playedWidth < 0 ? 0 : playedWidth > barBodyWidth ? barBodyWidth : playedWidth
        // onChange ? onChange(currentTime) : this.setState({ playedWidthState })
        // 先滑动到指定位置。
        this.setState({ playedWidthState })
        // 更新ballCurPageX的实际位置。不更新的话会进行每次的宽度累加。
        this.ballCurPageX += moveDistance
    }
    // 滑动停止之后，才真正回调onChange，然后再用真正的currentTime渲染playedbar的宽度。
    onTouchEnded(e) {
        console.log('onTouchEnded:', e);
        e.stopPropagation();
        // 如果null，则说明刚才没有BallTouched，则忽略本事件 
        if (this.ballCurPageX === null) {
            return
        }
        const { onChange } = this.props
        const barBodyWidth = this.barBody.vnode.dom.clientWidth;
        const playedWidth = this.state.playedWidthState
        // 计算需要调整的进度，把宽度转换为时间。
        const currentTime = this.props.totalTime * (playedWidth / barBodyWidth);
        onChange && onChange(currentTime)
        this.ballCurPageX = null
    }
    // 秒转换-分:秒的格式
    getTime = time => {
        if (time) {
            const minute = parseInt((time / 60) % 60);
            const second = parseInt(time % 60);
            let minuteText = `${minute}`;
            let secondText = `${second}`;
            if (minute < 10) {
                minuteText = `0${minute}`;
            }
            if (second < 10) {
                secondText = `0${second}`;
            }
            return `${minuteText}:${secondText}`;
        } else {
            return "00:00";
        }
    }

    render() {
        const { totalTime, currentTime, bufferedTime } = this.props;
        const { playedWidthState } = this.state;
        // 根据currentTime是否为undefined, 选择currentTime 或者 playedWidthState 作为 playedWidth 的计算依据
        //  this.ballCurPageX != null 说明正在进行滑动。这时候停止音频对滑动的更新。
        const playedWidth = (currentTime === undefined || this.ballCurPageX != null) ? playedWidthState : (totalTime ? `${currentTime / totalTime * 100}%` : 0);
        const bufferedWidth = totalTime ? `${bufferedTime / totalTime * 100}%` : 0;
        // 判断played进度条的动画过度时间，如果是点击或者拖动则过度时间为0,否则设置1s的过度时间,用来防止进度条跳动。
        // const transitionDuration = this.userOperation ? "0s" : "1s";
        const transitionDuration = this.userOperation ? "0s" : "1s";
        this.userOperation = false;
        return (
            <View className={styles.barBox} onTouchMove={this.onTouchMoved.bind(this)} onTouchEnd={this.onTouchEnded.bind(this)}>
                <View className={styles.timeTag}>{this.getTime(currentTime)}</View>
                <View className={styles.barBody} ref={ref => (this.barBody = ref)} onClick={this.onBarBodyClick.bind(this)}>
                    <View className={styles.played} ref={ref => (this.played = ref)} style={{ width: playedWidth, transitionDuration }}>
                        {
                            totalTime ? (
                                <View className={styles.ball} onTouchStart={this.onBallTouched.bind(this)} ><View className={styles.innerDot}></View></View>
                            ) : <AtActivityIndicator className={styles.ballLoading} color='#13CE66' size={16} />

                        }

                    </View>
                    <View className={styles.buffered} style={{ width: bufferedWidth }}></View>
                </View>
                <View className={styles.timeTag}>{this.getTime(totalTime)}</View>
            </View>
        )
    }
}
